package com.vm.osm.business.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.vm.osm.business.common.exception.BusinessException;
import com.vm.osm.business.dao.OsmLogicEquMapper;
import com.vm.osm.business.dto.eam.equ_part.BatchAddEamEquPartReq;
import com.vm.osm.business.dto.req.logic_equ.AddLogicEquReq;
import com.vm.osm.business.dto.req.logic_equ.LogicEquPageReq;
import com.vm.osm.business.dto.req.logic_equ.UpdateLogicEquReq;
import com.vm.osm.business.dto.rsp.logic_equ.GetLogicEquDetailRsp;
import com.vm.osm.business.dto.rsp.logic_equ.LogicEquBelonger;
import com.vm.osm.business.dto.rsp.logic_equ.LogicEquPageRsp;
import com.vm.osm.business.dto.rsp.logic_equ.LogicEquRow;
import com.vm.osm.business.entity.*;
import com.vm.osm.business.service.*;
import com.vm.osm.business.service.eam.IEamEquPartService;
import com.vm.osm.business.util.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 逻辑设备服务实现类
 *
 * @author Xuerong Xue
 */
@Service
public class OsmLogicEquServiceImpl
        extends AbstractServiceImpl<OsmLogicEqu, String> implements IOsmLogicEquService {
    private OsmLogicEquMapper mapper;
    @Autowired
    private IOrderFailureService orderFailureService;
    @Autowired
    private IOsmServerProviderService osmServerProviderService;
    @Autowired
    private IOsmLogicEquAttrService osmLogicEquAttrService;
    @Autowired
    private IOsmLogicEquPartService osmLogicEquPartService;
    @Autowired
    private IEamEquPartService eamEquPartService;

    public OsmLogicEquServiceImpl(OsmLogicEquMapper mapper) {
        super(mapper);
        this.mapper = mapper;
    }

    @Override
    public LogicEquPageRsp page(LogicEquPageReq request) {
        Map<String, Object> params = new HashMap<>();
        params.put("name", request.getName());
        params.put("logic_no_id", request.getLogic_no_id());
        params.put("equ_type", request.getEqu_type());
        params.put("equ_type_id", request.getEqu_type_id());
        if (null != request.getField_type()) {
            switch (request.getField_type()) {
                case 1: // 设备品牌
                    params.put("brand_blur", request.getField_value());
                    break;
                case 2: // 设备型号
                    params.put("model_blur", request.getField_value());
                    break;
                case 3: // 设备编码
                    params.put("equ_code_blur", request.getField_value());
                    break;
                case 4: // 所属客户
                    params.put("provider_name_blur", request.getField_value());
                    break;
            }
        }
        Page page = PageHelper.startPage(request.getPage_num(), request.getPage_size(), true);
        List<LogicEquRow> rows = mapper.page(params);
        LogicEquPageRsp rspBean = new LogicEquPageRsp();
        rspBean.setData_list(rows);
        rspBean.setPage_num(request.getPage_num());
        rspBean.setPage_size(request.getPage_size());
        rspBean.setTotal_num(page.getTotal());
        return rspBean;
    }

    @Override
    public GetLogicEquDetailRsp detail(String id) {
        OsmLogicEqu equ = selectByPrimaryKey(id);
        if (null == equ) throw new BusinessException("设备不存在");
        GetLogicEquDetailRsp rspbean = new GetLogicEquDetailRsp();
        BeanUtils.copyProperties(equ, rspbean);
        return rspbean;
    }

    @Override
    @Transactional
    public void delete(String id) {
        OsmLogicEqu equ = selectByPrimaryKey(id);
        if (null == equ) throw new BusinessException("设备不存在");
        Map<String, Object> params = new HashMap<>();
        params.put("device_id", id);
        OsmOrderFailure order = orderFailureService.get(params);
        if (null != order) throw new BusinessException("该设备有关联工单，不能删除");
        OsmLogicEqu temp = new OsmLogicEqu();
        temp.setId(id);
        temp.setIs_delete(OsmLogicEqu.IsDelete.YES);
        temp.setModified_time(new Date());
        updateByPrimaryKeySelective(temp);
    }

    @Override
    @Transactional
    public void batchDelete(List<String> ids) {
        if (null == ids) throw new BusinessException("id列表不能为空");
        ids.forEach(this::delete);
    }

    @Override
    public List<LogicEquBelonger> candidate(String company_id) {
        if (StringUtils.isEmpty(company_id)) throw new BusinessException("企业Id为空");
        Map<String, Object> params = new HashMap<>();
        params.put("company_id", company_id);
        params.put("status", "00001");
        List<LogicEquBelonger> candidates = new LinkedList<>();
        List<OsmServerProvider> list = osmServerProviderService.find(params);
        list.forEach(item -> {
            LogicEquBelonger belonger = new LogicEquBelonger();
            belonger.setBelonger_id(item.getProviderId());
            belonger.setBelonger_name(item.getProviderName());
            candidates.add(belonger);
        });
        LogicEquBelonger belonger = new LogicEquBelonger();
        belonger.setBelonger_id("0");
        belonger.setBelonger_name("自有设备");
        candidates.add(0, belonger);
        return candidates;
    }

    @Override
    @Transactional
    public void add(AddLogicEquReq request) {
        if (null == request) throw new BusinessException("请求参数为空");
        final Date NOW = new Date();
        OsmLogicEqu equ = new OsmLogicEqu();
        BeanUtils.copyProperties(request, equ);
        if (StringUtils.isEmpty(request.getEqu_code())) {
            equ.setEqu_code("QY" + DateFormatUtils.formate(new Date(), "yyyyMMddhhmmss"));
        }
        equ.setId(UUID.randomUUID().toString());
        equ.setCreate_mode(request.getAdd_type());
        equ.setCreate_time(NOW);
        equ.setModified_time(NOW);
        // 保存设备通用属性
        if (null == request.getCommon_attr_list()) throw new BusinessException("设备通用属性为空");
        request.getCommon_attr_list().forEach(item -> {
            switch (item.getField_key()) {
                case "model":
                    equ.setModel(item.getField_value());
                    break;
                case "brand":
                    equ.setBrand(item.getField_value());
                    break;
                case "purchase_date":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        equ.setPurchase_date(DateFormatUtils.millionSecondsToDate(Long.parseLong(item.getField_value())));
                    }
                    break;
                case "maintenance_period":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        equ.setMaintenance_period(DateFormatUtils.millionSecondsToDate(Long.parseLong(item.getField_value())));
                    }
                    break;
                case "original_value":
                    equ.setOriginal_value(item.getField_value());
                    break;
                case "scrap_ratio":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        equ.setScrap_ratio(new BigDecimal(item.getField_value()));
                    }
                    break;
                case "service_provider_id":
                    equ.setService_provider_id(item.getField_value());
                    break;
                case "project_id":
                    equ.setProject_id(item.getField_value());
                    break;
                case "equ_name":
                    equ.setEqu_name(item.getField_value());
                    break;
                case "manufactor_id":
                    equ.setManufactor_id(item.getField_value());
                    break;
                case "sn":
                    equ.setSn(item.getField_value());
                    break;
                case "measure_unit":
                    equ.setMeasure_unit(item.getField_value());
                    break;
                case "supplier_id":
                    equ.setSupplier_id(item.getField_value());
                    break;
                case "img_url":
                    equ.setImg_url(item.getField_value());
                    break;
                case "attachment":
                    equ.setAttachment(item.getField_value());
                    break;
                case "remark":
                    equ.setRemark(item.getField_value());
                    break;
                case "production_date":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        equ.setProduction_date(DateFormatUtils.millionSecondsToDate(Long.parseLong(item.getField_value())));
                    }
                    break;
                case "resource_name":
                    equ.setResource_name(item.getField_value());
                    break;
                case "resource_code":
                    equ.setResource_code(item.getField_value());
                    break;
                case "use_limit":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        equ.setUse_limit(Integer.parseInt(item.getField_value()));
                    }
                    break;
                case "address":
                    equ.setAddress(item.getField_value());
                    break;
                default:
                    LOG.warn("【逻辑设备】（新增） -> 未知的通用属性：key={}，value={}", item.getField_key(), item.getField_value());
                    break;
            }
        });
        insertSelective(equ);

        // 设置设置自定义属性
        if (null != request.getDiy_field_list()) {
            request.getDiy_field_list().forEach(item -> {
                OsmLogicEquAttr attr = new OsmLogicEquAttr();
                attr.setId(UUID.randomUUID().toString());
                attr.setEqu_id(equ.getId());
                attr.setAttr_id(item.getId());
                attr.setAttr_value(item.getField_value());
                attr.setCreate_time(NOW);
                attr.setModified_time(NOW);
                osmLogicEquAttrService.insertSelective(attr);
            });
        }
        if (null != request.getEqu_part_list()) {
            List<BatchAddEamEquPartReq.EquPart> part_list = new LinkedList<>();
            request.getEqu_part_list().forEach(item -> {
                if (StringUtils.isEmpty(item.getId())) {
                    BatchAddEamEquPartReq.EquPart part = new BatchAddEamEquPartReq.EquPart();
                    BeanUtils.copyProperties(item, part);
                    part_list.add(part);
                } else {
                    OsmLogicEquPart part = new OsmLogicEquPart();
                    part.setId(UUID.randomUUID().toString());
                    part.setEqu_id(equ.getId());
                    part.setPart_id(item.getId());
                    part.setCreate_time(NOW);
                    part.setModified_time(NOW);
                    osmLogicEquPartService.insertSelective(part);
                }
            });
            if (!part_list.isEmpty()) {
                BatchAddEamEquPartReq add_req = new BatchAddEamEquPartReq();
                add_req.setSession_id(request.getSession_id());
                add_req.setEnterprise_id(request.getEnterprise_id());
                add_req.setEqu_part_list(part_list);
                List<String> ids = eamEquPartService.batchAdd(add_req);
                if (null != ids) {
                    ids.forEach(item -> {
                        OsmLogicEquPart part = new OsmLogicEquPart();
                        part.setId(UUID.randomUUID().toString());
                        part.setEqu_id(equ.getId());
                        part.setPart_id(item);
                        part.setCreate_time(NOW);
                        part.setModified_time(NOW);
                        osmLogicEquPartService.insertSelective(part);
                    });
                }
            }
        }
    }

    @Override
    public void update(UpdateLogicEquReq request) {
        if (null == request) throw new BusinessException("请求参数为空");
        final Date NOW = new Date();
        OsmLogicEqu equ = selectByPrimaryKey(request.getId());
        if (null == equ) throw new BusinessException("设备不存在");
        OsmLogicEqu temp = new OsmLogicEqu();
        BeanUtils.copyProperties(request, temp);
        if (StringUtils.isEmpty(request.getEqu_code())) {
            temp.setEqu_code("QY" + DateFormatUtils.formate(new Date(), "yyyyMMddhhmmss"));
        }
        temp.setId(equ.getId());
        temp.setModified_time(NOW);
        // 更新逻辑设备信息
        if (null == request.getCommon_attr_list()) throw new BusinessException("设备通用属性为空");
        request.getCommon_attr_list().forEach(item -> {
            switch (item.getField_key()) {
                case "model":
                    temp.setModel(item.getField_value());
                    break;
                case "brand":
                    temp.setBrand(item.getField_value());
                    break;
                case "purchase_date":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        temp.setPurchase_date(DateFormatUtils.millionSecondsToDate(Long.parseLong(item.getField_value())));
                    }
                    break;
                case "maintenance_period":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        temp.setMaintenance_period(DateFormatUtils.millionSecondsToDate(Long.parseLong(item.getField_value())));
                    }
                    break;
                case "original_value":
                    temp.setOriginal_value(item.getField_value());
                    break;
                case "scrap_ratio":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        temp.setScrap_ratio(new BigDecimal(item.getField_value()));
                    }
                    break;
                case "service_provider_id":
                    temp.setService_provider_id(item.getField_value());
                    break;
                case "project_id":
                    temp.setProject_id(item.getField_value());
                    break;
                case "equ_name":
                    temp.setEqu_name(item.getField_value());
                    break;
                case "manufactor_id":
                    temp.setManufactor_id(item.getField_value());
                    break;
                case "sn":
                    temp.setSn(item.getField_value());
                    break;
                case "measure_unit":
                    temp.setMeasure_unit(item.getField_value());
                    break;
                case "supplier_id":
                    equ.setSupplier_id(item.getField_value());
                    break;
                case "img_url":
                    temp.setImg_url(item.getField_value());
                    break;
                case "attachment":
                    temp.setAttachment(item.getField_value());
                    break;
                case "remark":
                    temp.setRemark(item.getField_value());
                    break;
                case "production_date":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        temp.setProduction_date(DateFormatUtils.millionSecondsToDate(Long.parseLong(item.getField_value())));
                    }
                    break;
                case "resource_name":
                    temp.setResource_name(item.getField_value());
                    break;
                case "resource_code":
                    temp.setResource_code(item.getField_value());
                    break;
                case "use_limit":
                    if (!StringUtils.isEmpty(item.getField_value())) {
                        temp.setUse_limit(Integer.parseInt(item.getField_value()));
                    }
                    break;
                case "address":
                    temp.setAddress(item.getField_value());
                    break;
                default:
                    LOG.warn("【逻辑设备】（更新） -> 未知的通用属性：key={}，value={}", item.getField_key(), item.getField_value());
                    break;
            }
        });
        updateByPrimaryKeySelective(temp);
        // 删除旧的自定义属性
        osmLogicEquAttrService.deleteByEquId(equ.getId());
        // 设置新的自定义属性
        if (null != request.getDiy_field_list()) {
            request.getDiy_field_list().forEach(item -> {
                OsmLogicEquAttr attr = new OsmLogicEquAttr();
                attr.setId(UUID.randomUUID().toString());
                attr.setEqu_id(equ.getId());
                attr.setAttr_id(item.getId());
                attr.setAttr_value(item.getField_value());
                attr.setCreate_time(NOW);
                attr.setModified_time(NOW);
                osmLogicEquAttrService.insertSelective(attr);
            });
        }
        osmLogicEquPartService.deleteByEquId(equ.getId());
        if (null != request.getEqu_part_list()) {
            List<BatchAddEamEquPartReq.EquPart> part_list = new LinkedList<>();
            request.getEqu_part_list().forEach(item -> {
                if (StringUtils.isEmpty(item.getId())) {
                    BatchAddEamEquPartReq.EquPart part = new BatchAddEamEquPartReq.EquPart();
                    BeanUtils.copyProperties(item, part);
                    part_list.add(part);
                } else {
                    OsmLogicEquPart part = new OsmLogicEquPart();
                    part.setId(UUID.randomUUID().toString());
                    part.setEqu_id(equ.getId());
                    part.setPart_id(item.getId());
                    part.setCreate_time(NOW);
                    part.setModified_time(NOW);
                    osmLogicEquPartService.insertSelective(part);
                }
            });
            if (!part_list.isEmpty()) {
                BatchAddEamEquPartReq add_req = new BatchAddEamEquPartReq();
                add_req.setSession_id(request.getSession_id());
                add_req.setEnterprise_id(request.getEnterprise_id());
                add_req.setEqu_part_list(part_list);
                List<String> ids = eamEquPartService.batchAdd(add_req);
                if (null != ids) {
                    ids.forEach(item -> {
                        OsmLogicEquPart part = new OsmLogicEquPart();
                        part.setId(UUID.randomUUID().toString());
                        part.setEqu_id(equ.getId());
                        part.setPart_id(item);
                        part.setCreate_time(NOW);
                        part.setModified_time(NOW);
                        osmLogicEquPartService.insertSelective(part);
                    });
                }
            }
        }
    }

    @Override
    public OsmLogicEqu get(Map<String, Object> params) {
        return mapper.get(params);
    }
}
